<template>
		<view  v-if="showMask" class="l-0 t-0" :style="[
			_inContent&&!isNvue?{ width:'100%', height: '100%',top:'0px',position:'absolute'}:{ width: width + 'px', height: height + 'px',top:top+'px',position:'fixed'},
			zIndex ? { zIndex: zIndex } : '']">
			<view ref="overlay"
				:class="[bgColor_rp&&!props.transprent&&ani?'blurOn':'blurOff','overlay']"
				:style="[bgColor_rp&&!props.transprent ? { backgroundColor: showMask?bgColor_rp:'' } : '',
				_inContent&&!isNvue?{ width:'100%', height: '100%'}:{ width: width + 'px', height: height + 'px'},
				{ transitionDuration: props.duration+'ms'}
				 ]"
				>
				
			</view>
			<!-- #ifndef APP-NVUE -->
			<view @click.stop="closeByclick" :class="[align_rpx,' absolute flex flex-col  l-0 t-0 ',customClass,
			
			props.contentAnimation?'overlay':'',
			props.contentAnimation&&ani?'blurOnOpacity ':'',
			props.contentAnimation&&!ani?'blurOffOpacity overlay':'',
			
			]" 
			:style="[
				_inContent&&!isNvue?{ width:'100%', height: '100%',top:'0px'}:{ width: width + 'px', height: height + 'px'},
				customCSSStyle]">
				<slot></slot>
			</view>
			<!-- #endif -->
			<!-- #ifdef APP-NVUE -->
			<view @click.stop="closeByclick" :class="[align_rpx,' absolute flex flex-col  l-0 t-0 ',customClass]" 
			:style="[
				_inContent&&!isNvue?{ width:'100%', height: '100%',top:'0px'}:{ width: width + 'px', height: height + 'px'},
				customCSSStyle]">
				<slot></slot>
			</view>
			<!-- #endif -->
		</view>
		
	
</template>
<script lang="ts" setup>
	/**
	 * 遮罩层
	 * @description 遮罩层全屏弹出。
	 */
	import {
		getCurrentInstance,
		computed,
		ref,
		provide,
		inject,
		onMounted,
		onUnmounted,
		nextTick,
		watch,
		ComponentInternalInstance
	} from 'vue';
	import {
		cssstyle,
		tmVuetify
	} from '../../tool/lib/interface';
	import {
		custom_props,
		computedClass,
		computedStyle
	} from '../../tool/lib/minxs';
	// #ifdef APP-PLUS-NVUE
	const dom = uni.requireNativePlugin('dom')
	const animation = uni.requireNativePlugin('animation')
	// #endif
	const defaultBgColor = "rgba(0,0,0,0.24)"
	// 混淆props共有参数
	const props = defineProps({
		...custom_props,
		// 内容的对齐方式的类
		align: {
			type: String,
			default: 'flex-col-center-center'
		},
		//当前组件的主题。可以是颜色值，也可以是主题名称。
		bgColor: {
			type: String,
			default: "rgba(0,0,0,0.24)"
		},
		zIndex: {
			type: [Number, String],
			default: 999
		},
		show: {
			type: Boolean,
			default: false
		},
		overlayClick: {
			type: Boolean,
			default: true
		},
		transprent: {
			type: [Boolean, String],
			default: false
		},
		duration: {
			type: Number,
			default: 300
		},
		contentAnimation:{
			type: Boolean,
			default: false
		},
		/** 是否嵌入弹层，开启后将在它的父组件内执行弹层。 */
		inContent:{
			type: Boolean,
			default: false
		}
	});
	const emits = defineEmits(['click', 'open', 'close', 'update:show']);
	const proxy = getCurrentInstance()?.proxy ?? null;
	//自定义样式：
	const customCSSStyle = computedStyle(props);
	//自定类
	const customClass = computedClass(props);
	const sysinfo = inject("tmuiSysInfo",computed(()=>{
		return {bottom:0,height:750,width:uni.upx2px(750),top:0,isCustomHeader:false,sysinfo:null}
	}))
	const width = computed(()=>sysinfo.value.width)
	const height = computed(()=>sysinfo.value.height)
	const top = computed(()=>sysinfo.value.top)
	const isAniing = ref(false)
	let timids = uni.$tm.u.getUid(1);
	let timerId = NaN;
	const animationData = ref(null)
	const showMask = ref(false)
	const ani = ref(false)
	onUnmounted(() => clearTimeout(timerId))
	const align_rpx = computed(() => props.align)
	
	const bgColor_rp = computed(() => {
		if (!props.bgColor || props.transprent) return 'rgba(0,0,0,0)';
		return props.bgColor || defaultBgColor;
	})
	const _inContent = ref(props.inContent)
	const isNvue = ref(false)
	// #ifdef APP-NVUE
	_inContent.value = false;
	isNvue.value = true;
	// #endif
	let parent:any = null;
	onMounted(() => {
		if (!props.show) return;
		open(props.show)
	})



	function debounce(func: Function, wait = 500, immediate = false) {
		// 清除定时器
		if (!isNaN(timerId)) clearTimeout(timerId);
		// 立即执行，此类情况一般用不到
		if (immediate) {
			var callNow = !timerId;
			timerId = setTimeout(() => {
				timerId = NaN;
			}, wait);
			if (callNow) typeof func === "function" && func();
		} else {
			// 设置定时器，当最后一次操作后，timeout不会再被清除，所以在延时wait毫秒后执行func回调方法
			timerId = setTimeout(() => {
				typeof func === "function" && func();
			}, wait);
		}
	}

	function close() {

		if (timerId) {
			clearTimeout(timerId)
			timerId = NaN
		}
		open(false)
	}

	function closeByclick(e: Event) {
		try {
			e.stopPropagation()
			e.stopImmediatePropagation()
		} catch (e) {
			//TODO handle the exception
		}
		emits('click', e);
		if (timerId) {
			clearTimeout(timerId)
			timerId = NaN
		}
		if (!props.overlayClick) return;
		open(false)
	}

	function open(off: boolean) {
		if (off == true) {
			uni.hideKeyboard()
		}
		// #ifdef APP-NVUE
		fadeInNvue(off);
		// #endif

		// #ifndef APP-NVUE
		fadeInVue(off)
		// #endif
	}

	function fadeInNvue(off: boolean = false) {
		if (off == false) {
			if (showMask.value == off) return;
			var testEl = proxy?.$refs?.overlay;
			animation.transition(testEl, {
				styles: {
					backgroundColor: bgColor_rp.value,
					opacity: 0
				},
				duration: props.duration || 1, //ms
				timingFunction: 'linear',
				delay: 0 //ms
			}, () => {
				showMask.value = off;
				emits('close');
				emits('update:show', false);
				// isAniing.vale = false;
			})
		} else {
			showMask.value = off;
			emits('open');
			clearTimeout(timids)
			timids = setTimeout(function() {
				var testEl = proxy?.$refs.overlay;
				animation.transition(testEl, {
					styles: {
						backgroundColor: bgColor_rp.value,
						opacity: 1
					},
					duration: props.duration || 1, //ms
					timingFunction: 'linear',
					delay: 0 //ms
				}, () => {

				})
			}, 50);


		}
	}
	function fadeInVue(off = false) {
		
		if (showMask.value == off) return;
		debounce(function() {
			if (off == false) {
				ani.value = false;
				setTimeout(function() {
					showMask.value = off;
					emits('close');
					emits('update:show', false);
				}, props.duration+10);
			} else {
				showMask.value = true
				setTimeout(function() {
					ani.value = true;
				}, 10);
				emits('open');
				setTimeout(function() {
					emits('update:show', true);
				}, props.duration);
			}
		}, props.duration+10, true)
	}
	watch(() => props.show, (newval) => {
		open(newval)
	})
	defineExpose({
		close: close,
		open: open
	})
</script>

<style scoped="scoped">
.overlay{
	transition-timing-function:ease;
	transition-property: opacity;
	transition-delay: 0;
	opacity: 0;
}
.blurOn{
	/* #ifndef APP-PLUS-NVUE */
	backdrop-filter: blur(2px);
	/* #endif */
	opacity: 1;
}
.blurOff{
	/* #ifndef APP-PLUS-NVUE */
	backdrop-filter: blur(0px);
	/* #endif */
	opacity: 0;
}

.blurOnOpacity{
	opacity: 1;
}
.blurOffOpacity{
	opacity: 0;
}
</style>
